-
1. DĂ©marrage rapide
-
2. Les bases de Git
-
3. Les branches avec Git
-
4. Git sur le serveur
- 4.1 Protocoles
- 4.2 Installation de Git sur un serveur
- 4.3 Génération des clés publiques SSH
- 4.4 Mise en place du serveur
- 4.5 DĂ©mon (Daemon) Git
- 4.6 HTTP intelligent
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git hébergé
- 4.10 Résumé
-
5. Git distribué
-
6. GitHub
-
7. Utilitaires Git
- 7.1 SĂ©lection des versions
- 7.2 Indexation interactive
- 7.3 Remisage et nettoyage
- 7.4 Signer votre travail
- 7.5 Recherche
- 7.6 RĂ©Ă©crire lâhistorique
- 7.7 Reset démystifié
- 7.8 Fusion avancée
- 7.9 Rerere
- 7.10 DĂ©boguer avec Git
- 7.11 Sous-modules
- 7.12 Empaquetage (bundling)
- 7.13 Replace
- 7.14 Stockage des identifiants
- 7.15 Résumé
-
8. Personnalisation de Git
- 8.1 Configuration de Git
- 8.2 Attributs Git
- 8.3 Crochets Git
- 8.4 Exemple de politique gérée par Git
- 8.5 Résumé
-
9. Git et les autres systĂšmes
- 9.1 Git comme client
- 9.2 Migration vers Git
- 9.3 Résumé
-
10. Les tripes de Git
- 10.1 Plomberie et porcelaine
- 10.2 Les objets de Git
- 10.3 Références Git
- 10.4 Fichiers groupés
- 10.5 La refspec
- 10.6 Les protocoles de transfert
- 10.7 Maintenance et récupération de données
- 10.8 Les variables dâenvironnement
- 10.9 Résumé
-
A1. Annexe A: Git dans dâautres environnements
- A1.1 Interfaces graphiques
- A1.2 Git dans Visual Studio
- A1.3 Git dans Visual Studio Code
- A1.4 Git dans IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git dans Sublime Text
- A1.6 Git dans Bash
- A1.7 Git dans Zsh
- A1.8 Git dans PowerShell
- A1.9 Résumé
-
A2. Annexe B: Embarquer Git dans vos applications
- A2.1 Git en ligne de commande
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Commandes Git
- A3.1 Installation et configuration
- A3.2 Obtention et création des projets
- A3.3 Capture dâinstantanĂ© basique
- A3.4 Création de branches et fusion
- A3.5 Partage et mise Ă jour de projets
- A3.6 Inspection et comparaison
- A3.7 DĂ©bogage
- A3.8 Patchs
- A3.9 Courriel
- A3.10 SystĂšmes externes
- A3.11 Administration
- A3.12 Commandes de plomberie
3.2 Les branches avec Git - Branches et fusions : les bases
Branches et fusions : les bases
Prenons un exemple simple faisant intervenir des branches et des fusions (merges) que vous pourriez trouver dans le monde réel. Vous effectuez les tùches suivantes :
-
vous travaillez sur un site web ;
-
vous créez une branche pour un nouvel article en cours ;
-
vous commencez Ă travailler sur cette branche.
Ă cette Ă©tape, vous recevez un appel pour vous dire quâun problĂšme critique a Ă©tĂ© dĂ©couvert et quâil faut le rĂ©gler au plus tĂŽt. Vous faites donc ce qui suit :
-
vous basculez sur la branche de production ;
-
vous créez une branche pour y ajouter le correctif ;
-
aprĂšs lâavoir testĂ©, vous fusionnez la branche du correctif et poussez le rĂ©sultat en production ;
-
vous rebasculez sur la branche initiale et continuez votre travail.
Branches
Commençons par supposer que vous travaillez sur votre projet et avez déjà quelques commits sur la branche master
.
Vous avez dĂ©cidĂ© de travailler sur le problĂšme numĂ©rotĂ© #53 dans lâoutil de gestion des tĂąches que votre entreprise utilise, quel quâil soit.
Pour créer une branche et y basculer tout de suite, vous pouvez lancer la commande git checkout
avec lâoption -b
 :
$ git checkout -b iss53
Switched to a new branch "iss53"
Cette commande est un raccourci pour :
$ git branch iss53
$ git checkout iss53
Vous travaillez sur votre site web et validez vos modifications.
Ce faisant, la branche iss53
avance parce que vous lâavez extraite (câest-Ă -dire que votre pointeur HEAD
pointe dessus)Â :
$ vim index.html
$ git commit -a -m "ajout d'un pied de page [problĂšme 53]"
Ă ce moment-lĂ , vous recevez un appel qui vous apprend quâil y a un problĂšme sur le site web quâil faut rĂ©soudre immĂ©diatement.
Avec Git, vous nâavez pas Ă dĂ©ployer en mĂȘme temps votre correctif et les modifications dĂ©jĂ validĂ©es pour iss53
et vous nâavez pas non plus Ă vous fatiguer Ă annuler ces modifications avant de pouvoir appliquer votre correctif sur ce quâil y a en production.
Tout ce que vous avez Ă faire, câest simplement de rebasculer sur la branche master
.
Cependant, avant de le faire, notez que si votre copie de travail ou votre zone dâindex contiennent des modifications non validĂ©es qui sont en conflit avec la branche que vous extrayez, Git ne vous laissera pas changer de branche.
Le mieux est dâavoir votre copie de travail propre au moment de changer de branche.
Il y a des moyens de contourner ceci (prĂ©cisĂ©ment par le remisage et lâamendement de commit) dont nous parlerons plus loin, au chapitre Remisage et nettoyage.
Pour lâinstant, nous supposons que vous avez validĂ© tous vos changements et que vous pouvez donc rebasculer vers votre branche master
 :
$ git checkout master
Switched to branch 'master'
Ă cet instant, votre rĂ©pertoire de copie de travail est exactement dans lâĂ©tat dans lequel vous lâaviez laissĂ© avant de commencer Ă travailler sur le problĂšme #53 et vous pouvez vous consacrer Ă votre correctif. Câest un point important Ă garder en mĂ©moire : quand vous changez de branche, Git rĂ©initialise votre rĂ©pertoire de travail pour quâil soit le mĂȘme que la derniĂšre fois que vous avez effectuĂ© un commit sur cette branche. Il ajoute, retire et modifie automatiquement les fichiers de maniĂšre Ă sâassurer que votre copie de travail soit identique Ă ce quâelle Ă©tait lors de votre dernier commit sur cette branche.
Vous avez ensuite un correctif Ă faire.
Pour ce faire, créons une branche hotfix
sur laquelle travailler jusquâĂ rĂ©solution du problĂšme :
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m "correction de l'adresse email incorrecte"
[hotfix 1fb7853] "correction de l'adresse email incorrecte"
1 file changed, 2 insertions(+)
master
Vous pouvez lancer vos tests, vous assurer que la correction est efficace et la fusionner dans la branche master
pour la déployer en production.
Vous réalisez ceci au moyen de la commande git merge
 :
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
Vous noterez la mention fast-forward
lors de cette fusion (merge).
Comme le commit C4
pointé par la branche hotfix
que vous avez fusionnée était directement devant le commit C2
sur lequel vous vous trouvez, Git a simplement dĂ©placĂ© le pointeur (vers lâavant).
Autrement dit, lorsque lâon cherche Ă fusionner un commit qui peut ĂȘtre atteint en parcourant lâhistorique depuis le commit dâorigine, Git se contente dâavancer le pointeur car il nây a pas de travaux divergents Ă fusionner â ceci sâappelle un fast-forward
(avance rapide).
Votre modification est maintenant dans lâinstantanĂ© (snapshot) du commit pointĂ© par la branche master
et vous pouvez déployer votre correctif.
master
sur hotfix
AprĂšs le dĂ©ploiement de votre correctif super-important, vous voilĂ prĂȘt Ă retourner travailler sur le sujet qui vous occupait avant lâinterruption.
Cependant, vous allez avant cela effacer la branche hotfix
dont vous nâavez plus besoin puisque la branche master
pointe au mĂȘme endroit.
Vous pouvez lâeffacer avec lâoption -d
de la commande git branch
 :
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Maintenant, vous pouvez retourner travailler sur la branche qui contient vos travaux en cours pour le problĂšme #53Â :
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Nouveau pied de page terminé [issue 53]'
[iss53 ad82d7a] Nouveau pied de page terminé [issue 53]
1 file changed, 1 insertion(+)
iss53
Il est utile de noter que le travail réalisé dans la branche hotfix
nâest pas contenu dans les fichiers de la branche iss53
.
Si vous avez besoin de les y rapatrier, vous pouvez fusionner la branche master
dans la branche iss53
en lançant la commande git merge master
, ou vous pouvez retarder lâintĂ©gration de ces modifications jusquâĂ ce que vous dĂ©cidiez plus tard de rapatrier la branche iss53
dans master
.
Fusions (Merges)
Supposons que vous ayez dĂ©cidĂ© que le travail sur le problĂšme #53 Ă©tait terminĂ© et prĂȘt Ă ĂȘtre fusionnĂ© dans la branche master
.
Pour ce faire, vous allez fusionner votre branche iss53
de la mĂȘme maniĂšre que vous lâavez fait plus tĂŽt pour la branche hotfix
.
Tout ce que vous avez Ă faire est dâextraire la branche dans laquelle vous souhaitez fusionner et lancer la commande git merge
:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
README | 1 +
1 file changed, 1 insertion(+)
Le comportement semble légÚrement différent de celui observé pour la fusion précédente de la branche hotfix
.
Dans ce cas, Ă un certain moment, lâhistorique de dĂ©veloppement a divergĂ©.
Comme le commit sur la branche sur laquelle vous vous trouvez nâest plus un ancĂȘtre direct de la branche que vous cherchez Ă fusionner, Git doit effectuer quelques actions.
Dans ce cas, Git rĂ©alise une simple fusion Ă trois sources (three-way merge), en utilisant les deux instantanĂ©s pointĂ©s par les sommets des branches ainsi que leur plus proche ancĂȘtre commun.
Au lieu dâavancer simplement le pointeur de branche, Git crĂ©e un nouvel instantanĂ© qui rĂ©sulte de la fusion Ă trois sources et crĂ©e automatiquement un nouveau commit qui pointe dessus. On appelle ceci un commit de fusion (merge commit) qui est spĂ©cial en cela quâil a plus dâun parent.
Ă prĂ©sent que votre travail a Ă©tĂ© fusionnĂ©, vous nâavez plus besoin de la branche iss53
.
Vous pouvez fermer le ticket dans votre outil de suivi des tùches et supprimer la branche :
$ git branch -d iss53
Conflits de fusions (Merge conflicts)
Quelques fois, le processus ci-dessus ne se déroule pas aussi bien.
Si vous avez modifiĂ© diffĂ©remment la mĂȘme partie du mĂȘme fichier dans les deux branches que vous souhaitez fusionner, Git ne sera pas capable de rĂ©aliser proprement la fusion.
Si votre rĂ©solution du problĂšme #53 a modifiĂ© la mĂȘme section de fichier que le hotfix
, vous obtiendrez un conflit qui ressemblera à ceci :
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git nâa pas automatiquement crĂ©Ă© le commit de fusion.
Il a arrĂȘtĂ© le processus le temps que vous rĂ©solviez le conflit.
Si vous voulez vĂ©rifier, Ă tout moment aprĂšs lâapparition du conflit, quels fichiers nâont pas Ă©tĂ© fusionnĂ©s, vous pouvez lancer la commande git status
 :
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Tout ce qui comporte des conflits et nâa pas Ă©tĂ© rĂ©solu est listĂ© comme unmerged
.
Git ajoute des marques de résolution de conflit standards dans les fichiers qui comportent des conflits, pour que vous puissiez les ouvrir et résoudre les conflits manuellement.
Votre fichier contient des sections qui ressemblent à ceci :
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Cela signifie que la version dans HEAD
(votre branche master
, parce que câest celle que vous aviez extraite quand vous avez lancĂ© votre commande de fusion) est la partie supĂ©rieure de ce bloc (tout ce qui se trouve au-dessus de la ligne =======
), tandis que la version de votre branche iss53
se trouve en dessous.
Pour rĂ©soudre le conflit, vous devez choisir une partie ou lâautre ou bien fusionner leurs contenus vous-mĂȘme.
Par exemple, vous pourriez choisir de résoudre ce conflit en remplaçant tout le bloc par ceci :
<div id="footer">
please contact us at email.support@github.com
</div>
Cette résolution comporte des éléments de chaque section et les lignes <<<<<<<
, =======
et >>>>>>>
ont été complÚtement effacées.
AprÚs avoir résolu chacune de ces sections dans chaque fichier comportant un conflit, lancez git add
sur chaque fichier pour le marquer comme résolu.
Placer le fichier dans lâindex marque le conflit comme rĂ©solu pour Git.
Si vous souhaitez utiliser un outil graphique pour résoudre ces conflits, vous pouvez lancer git mergetool
qui dĂ©marre lâoutil graphique de fusion appropriĂ© et vous permet de naviguer dans les conflits :
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Si vous souhaitez utiliser un outil de fusion autre que celui par défaut (Git a choisi opendiff
dans ce cas car la commande a Ă©tĂ© lancĂ©e depuis un Mac), vous pouvez voir tous les outils supportĂ©s aprĂšs lâindication « of the following tools: ».
Entrez simplement le nom de lâoutil que vous prĂ©fĂ©reriez utiliser.
Note
|
Si vous avez besoin dâoutils plus avancĂ©s pour rĂ©soudre des conflits complexes, vous trouverez davantage dâinformations au chapitre Fusion avancĂ©e. |
AprĂšs avoir quittĂ© lâoutil de fusion, Git vous demande si la fusion a Ă©tĂ© rĂ©ussie.
Si vous rĂ©pondez par la positive Ă lâoutil, il ajoute le fichier dans lâindex pour le marquer comme rĂ©solu.
Vous pouvez lancer Ă nouveau la commande git status
pour vérifier que tous les conflits ont été résolus :
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Si cela vous convient et que vous avez vĂ©rifiĂ© que tout ce qui comportait des conflits a Ă©tĂ© ajoutĂ© Ă lâindex, vous pouvez entrer la commande git commit
pour finaliser le commit de fusion.
Le message de validation par défaut ressemble à ceci :
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Vous pouvez modifier ce message pour inclure les dĂ©tails sur la maniĂšre dont le conflit a Ă©tĂ© rĂ©solu si vous pensez que cela peut ĂȘtre utile lors dâune revue ultĂ©rieure. Indiquez pourquoi vous avez fait ces choix, si ce nâest pas clair.